package cn.lhemi.iotweb.controller;

import cn.hutool.core.util.IdUtil;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Controller
@RequestMapping("/device")
@AllArgsConstructor
public class DeviceController {
    private final WxMpService wxMpService;

    private final static String BASE_MSG_URL = "http://amumu.iask.in/device/wxRedirect/";
    private final static String WX_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd8f99fcbabe6947c&redirect_uri=http%3a%2f%2famumu.iask.in%2fdevice%2fscan&response_type=code&scope=snsapi_base&state=";
    private final static String BASE_CHECK_URL = "http://amumu.iask.in/device/check/";
    private final static String BASE_RESULT_URL = "http://amumu.iask.in/device/result/";

    private static Map<String, DeferredResult<Object>> checkMap = new ConcurrentHashMap<>();
    private static Map<String, DeferredResult<Object>> resultMap = new ConcurrentHashMap<>();
    private static Map<String, String> imeiMap = new ConcurrentHashMap<>();

    @RequestMapping("/qrCodeMsg")
    @ResponseBody
    public Object qrCodeMsg(@RequestParam String imei) throws WxErrorException {
//        设置三分钟过期
        DeferredResult<Object> deferredResult = new DeferredResult<>(180000L);
        DeferredResult<Object> deferredResult1 = new DeferredResult<>(180000L);
        String uid = IdUtil.simpleUUID();
        System.out.println("uid:" + uid);
        checkMap.put(uid, deferredResult);
        resultMap.put(uid, deferredResult1);
        imeiMap.put(uid, imei);
//        String shortUrl = wxMpService.shortUrl(BASE_MSG_URL + uid);
        String shortUrl = wxMpService.shortUrl(WX_URL + uid);
        return new HashMap<String, Object>(2) {{
            put("code", 0);
            put("data", new HashMap<String, Object>(2) {{
                put("msg", shortUrl);
                put("checkUrl", BASE_CHECK_URL + uid);
            }});
        }};
    }

    @RequestMapping("/result/{uid}")
    @ResponseBody
    public Object result(@PathVariable String uid) {
        DeferredResult<Object> result = resultMap.get(uid);
//        不存在就新建
        if (null == result || result.isSetOrExpired()) {
            resultMap.remove(uid);
            return 2;
        }
        return result;
    }

    @RequestMapping("/check/{uid}")
    @ResponseBody
    public Object check(@PathVariable String uid) {
        DeferredResult<Object> result = checkMap.get(uid);
//        不存在就新建
        if (null == result || result.isSetOrExpired()) {
            checkMap.remove(uid);
            return 2;
        }
        return result;
    }

    @RequestMapping("/scan")
    public Object scan(String code, @RequestParam("state") String uid, Model model) throws WxErrorException {
        WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
        System.out.println("openId:" + accessToken.getOpenId());
//        wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken,"zh_CN");
        DeferredResult<Object> result = checkMap.get(uid);
        model.addAttribute("sn", imeiMap.get(uid));
        model.addAttribute("uid", uid);
        if (null == result || result.isSetOrExpired()) {
            checkMap.remove(uid);
            model.addAttribute("state", -1);
            return "bindDevice";
        }
        model.addAttribute("state", 0);
        result.setResult(new HashMap<String, Object>(1) {{
            put("resultUrl", BASE_RESULT_URL + uid);
        }});
        return "bindDevice";
    }

    @RequestMapping("/confirm/{uid}")
    @ResponseBody
    public Object finish(@PathVariable String uid) {
        DeferredResult<Object> result = resultMap.get(uid);
        if (null == result || result.isSetOrExpired()) {
            checkMap.remove(uid);
            return "fail";
        }
        result.setResult(2);
        return "success";
    }

    @RequestMapping("/cancel/{uid}")
    @ResponseBody
    public Object cancel(@PathVariable String uid) {
        DeferredResult<Object> result = resultMap.get(uid);
        if (null == result || result.isSetOrExpired()) {
            checkMap.remove(uid);
            return "fail";
        }
        result.setResult(3);
        return "success";
    }

    @RequestMapping("/wxRedirect/{uid}")
    public Object wxRedirect(@PathVariable String uid) {
        return "redirect:" + WX_URL + uid;
    }

    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        for (int i = 0; i < 100; i++) {
            System.out.println(Base64Utils.encodeToString(("ML:" + IdUtil.simpleUUID()).getBytes(Charset.forName("UTF-8"))));
//            System.out.println(("ML-"+(UUID.randomUUID())));
        }
    }
}
